import { AfterViewInit, Component, ElementRef, Input, OnInit, Renderer2, ViewEncapsulation } from '@angular/core';
import { FormlyFormOptions } from '@ngx-formly/core';
import { ApesField } from '@shared/ui-zorro/src/types/apes-field';
import { ExpressionService } from '@core/services/expression/ExpressionService';
import { Events } from '@core/services/events/Events';
import { SubjectService } from '@core/services/events/subject.service';
import { ApiService } from '@core/services/http/api.service';
import { ApesDrawerService } from '@shared/apes/drawer';
import { ApesDrawerRef } from '@shared/apes/drawer/apes-drawer-ref';
import { FormGroup } from '@angular/forms';
import { Observable } from 'rxjs';
import { deepClone, exists, fillField, getJson, getO, missingOrEmpty } from '../../../../utils/utils';
import { map } from 'rxjs/operators';
import { toBoolean } from '@shared/apes/core';

@Component({
  selector: 'formly-field-drawer',
  template: `
    <a [ngStyle]="{'margin-left':class}"
       style="line-height: 2.5"
       (click)="openComponent(to.label,to.hasOwnProperty('width') ? to.width:'600px')">
      <input [formControl]="formControl" (ngModelChange)="onModelChange($event)" style="display: none"/>
      {{title}}
    </a>
    <div *ngIf="showHideBtn && title && title != ''" class="drawer-showHidden-icon" (click)="openShowHidden()">
      <i *ngIf="!showHidden" apes-icon apesType="eye-invisible"></i>
      <i *ngIf="showHidden" apes-icon apesType="eye"></i>
    </div>
  `,
  styles: [`
    a {
      color: #0589DD;
    }

    a:hover {
      color: #4d76b3;
    }

    .drawer-showHidden-icon {
      display: inline-block;
      margin-left: 8px;
      cursor: pointer;
      position: relative;
      top: 1px;
    }
  `],
})
/*按钮*/
export class FormlyFieldDrawer extends ApesField {
  constructor(protected apiService: ApiService, protected events: Events,
              protected expressionService: ExpressionService, protected subject: SubjectService,
              protected elementRef: ElementRef, protected renderer: Renderer2,
              protected drawerService: ApesDrawerService) {
    super(apiService, events, expressionService, subject);
  }

  class = '20px';
  title: any;
  valueList: any;
  apiParams: any;

  showHideBtn: boolean = false;
  showHidden: boolean;

  onModelChange(value: any): void {
    if (value) {
      this.valueList = value;
      if (this.to.apiParams) {
        this.apiParams = fillField(getO(this.to.apiParams), this.formState, false, '');
      }
      let title;
      if (this.showHideBtn && !this.showHidden) {
        let hiddenRegExp = this.to.hiddenRegExp;
        if (hiddenRegExp) {
          let replaceValue = this.to.replaceValue;
          let regExpValue = this.formatter(value, this.getValueFormatter());
          // tslint:disable-next-line:no-eval
          hiddenRegExp = eval(hiddenRegExp);
          title = regExpValue.replace(hiddenRegExp, replaceValue);
        } else {
          title = '****';
        }
      } else {
        title = this.formatter(value, this.getValueFormatter());
      }
      this.title = title;
    } else {
      this.title = '';
    }
  }

  formatter(value: any, expression: string) {
    return this.expressionService.evaluate(expression, {
      context: {},
      model: {},
      value: value,
    });
  }

  getValueFormatter(): string {

    if (this.to.valueFormatter) return this.to.valueFormatter;

    if (this.to.states === 'customer') {
      return `'${this.to.label ? (this.to.label + ': ') : ''}' + '[' + (value.mobile ? value.mobile : '无手机号') + ']' + ' ' + (value.realname ? value.realname : '未知')`;
    } else if (this.to.states === 'customerCar') {
      return `'${this.to.label ? (this.to.label + ': ') : ''}' + value.carLicense`;
    } else if (this.to.states === 'inquiry') {
      return `'${this.to.label ? (this.to.label + ': ') : ''}' + value.name`;
    } else {
      return `'${this.to.label ? (this.to.label + ': ') : ''}' + '[' + value.id + ']' + ' ' + value.name`;
    }
  }

  ngOnInit(): void {
    this.addEventListener(this.elementRef, this.renderer);

    if (this.to.hasOwnProperty('showHidden')) {
      this.showHideBtn = true;
      this.showHidden = this.to.showHidden ? toBoolean(this.to.showHidden) : false;
    }

  }

  openComponent(title, width): void {
    const drawerRef = this.drawerService.create<ApesDrawerCustomComponent, { formId: string, api: string, value: any, apiParams: any, title: any, conditionModel: any }, string>({
      apesTitle: title,
      apesContent: ApesDrawerCustomComponent,
      apesWidth: width,
      apesContentParams: {
        formId: this.to.formId,
        api: this.to.api,
        value: this.valueList,
        apiParams: this.apiParams,
        title: title,
        conditionModel: this.model,
      },
    });
    drawerRef.afterOpen.subscribe(() => {
      console.log('Drawer(Component) open');
    });

    drawerRef.afterClose.subscribe(data => {
      if (typeof data === 'string') {

      }
    });
  }

  openShowHidden() {
    this.showHidden = !this.showHidden;
    let title;
    if (this.showHideBtn && !this.showHidden) {
      let hiddenRegExp = this.to.hiddenRegExp;
      if (hiddenRegExp) {
        let replaceValue = this.to.replaceValue;
        let regExpValue = this.formatter(this.valueList, this.getValueFormatter());
        // tslint:disable-next-line:no-eval
        hiddenRegExp = eval(hiddenRegExp);
        title = regExpValue.replace(hiddenRegExp, replaceValue);
      } else {
        title = '****';
      }
    } else {
      title = this.formatter(this.valueList, this.getValueFormatter());
    }
    this.title = title;
  }
}

@Component({
  selector: 'apes-drawer-custom-component',
  template: `
    <form [formGroup]="form">
      <form apes-form>
        <apes-container [datas]="formMetadata" [form]="form" [model]="model" [options]="options"
                        [apesPrefixCls]="'apes-container-drawer'" [isDrawer]="true">
        </apes-container>
      </form>
    </form>

  `,
  styles: [`
    .ui-scrollpanel-bar {
      display: none;
    }

    .apes-drawer-body {
      padding: 0;
    }

    .apes-drawer-custom-component .scroll-panel-div {
      padding: 0 !important;
    }
  `],
  encapsulation: ViewEncapsulation.None,
})
export class ApesDrawerCustomComponent implements OnInit, AfterViewInit {
  @Input() formId = '';
  @Input() api = '';
  form: any;
  model: any;
  formMetadata = [];
  ctx = {};
  /**订阅主题**/
  subjects = {};
  options: FormlyFormOptions = {};

  constructor(
    private drawerRef: ApesDrawerRef<string>,
    private apiService: ApiService,
    private subject: SubjectService,
    protected events: Events,
  ) {
  }

  ngOnInit() {
    this.form = new FormGroup({});
    this.model = {};
    this.ctx['model'] = this.model;
    this.ctx['subjects'] = this.subjects;
    this.options.formState = this.ctx;
    this.subject.publish(this.ctx, 'drawer', this.model);
    this.events.subscribe('drawer', () => {
      this.events.unsubscribe('drawer');
      this.drawerRef.close(this.formId);
    });
  }

  ngAfterViewInit(): void {
    const apesContentParams = this.drawerRef['apesContentParams'];
    let data = deepClone(apesContentParams.value);
    const apiParams = apesContentParams.apiParams;
    if (exists(apiParams)) {
      data = apiParams;
      this.ctx['condition'] = apiParams;
      this.ctx['condition'].link = apesContentParams.title;
    }
    let conditionModel = apesContentParams.conditionModel;
    if (conditionModel) {
      data['conditionModel'] = conditionModel;
      this.ctx['conditionModel'] = conditionModel;
    }
    this.apiService.post(this.api, data).pipe(map(
      (body) => {
        if (body) {
          this.model = body;
          this.ctx['model'] = this.model;
          this.subject.publish(this.ctx, 'drawer', this.model);
          this.getFormMetadata(this.formId);
        }
      })).subscribe();
  }

  close(): void {
    this.drawerRef.close(this.formId);
  }

  /**
   * 功能：获取表单元数据
   */
  private getFormMetadata(formId) {

    this.getFormMetadataApi(formId).pipe().subscribe((body) => {
      let metadata = body.sheet;
      // this.extFormMetadata(metadata);
      this.formMetadata = this.formMetadata.concat(metadata);
    });

  }

  private getFormMetadataApi(formId: string): Observable<any> {
    return this.apiService.post('form.get', { 'body': getJson({ id: formId }) }).pipe(map(
      (body) => {
        if (body) {
          return body;
        }
      }));
  }

  submit() {
    alert(JSON.stringify(this.model));
  }
}
